﻿
using Org.BouncyCastle.Bcpg.OpenPgp;

namespace LS.Nc6.Application.Cms
{
    /// <summary>
    /// 内容接口
    /// </summary>
    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    [ApiDescriptionSettings("CMS")]
    public class ContentService : IDynamicApiController
    {
        private readonly ISysUserService _userService;

        private readonly IHttpContextAccessor _httpContextAccessor;

        private readonly IEventPublisher _eventPublisher;

        private readonly ISysConfigurationService _configurationService;

        private readonly ICmsContentService _contentService;

        private readonly ISysFileService _fileService;

        private readonly ICache _cache;

        private readonly ICmsContentGroupService _cmsContentGroupService;
        private readonly ICmsContentTagService _cmsContentTagService;
        private readonly ICmsChannelService _channelService;
        public ContentService(ISysUserService userService, IEventPublisher eventPublisher, ISysConfigurationService configurationService, IHttpContextAccessor httpContextAccessor,
            ICmsContentService contentService, ISysFileService sysFileService, ICmsContentGroupService cmsContentGroupService, ICmsContentTagService cmsContentTagService,
            ICmsChannelService channelService,
            IOptions<CacheOptions> cacheOptions, Func<string, ISingleton, object> resolveNamed)
        {
            _userService = userService;
            _httpContextAccessor = httpContextAccessor;
            _eventPublisher = eventPublisher;
            _configurationService = configurationService;
            _contentService = contentService;
            _cache = resolveNamed(cacheOptions.Value.CacheType.ToString(), default) as ICache;
            _fileService = sysFileService;
            _cmsContentGroupService = cmsContentGroupService;
            _cmsContentTagService = cmsContentTagService;
            _channelService = channelService;
        }

        /// <summary>
        /// 获取内容分组
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("api/content/group")]
        public async Task<List<ContentGroupOutput>> GetContentGroup()
        {
            var result = await _cmsContentGroupService.List(a => true, a => a.Taxis);
            var datalist = result.Adapt<List<ContentGroupOutput>>();
            return datalist;
        }
        /// <summary>
        /// 获取内容分组
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("api/content/tag")]
        public async Task<List<ContentTagOutput>> GetContentTag()
        {
            var result = await _cmsContentTagService.List(a => true, a => a.Id);
            var datalist = result.Adapt<List<ContentTagOutput>>();
            return datalist;
        }

        /// <summary>
        /// 按条件获取内容List(栏目不查询子集,属性(顶,荐,热,醒 交集)图片只返回一张)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("api/content/pageList")]
        public async Task<PageResult<ContentPageOutput>> GetList([FromQuery]ContentInput input)
        {
            var expable = Expressionable.Create<CmsContentEntity>();
            expable.And(a => a.Checked == 3);
            expable.AndIF(!string.IsNullOrEmpty(input.Title), a => a.Title.Contains(input.Title));
            expable.AndIF(!string.IsNullOrEmpty(input.SubTitle), a => a.SubTitle.Contains(input.SubTitle));
            expable.AndIF(!string.IsNullOrEmpty(input.SubTitle), a => a.SubTitle.Contains(input.SubTitle));
            expable.AndIF(!string.IsNullOrEmpty(input.Author), a => a.SubTitle.Contains(input.Author));
            expable.AndIF(!string.IsNullOrEmpty(input.Source), a => a.SubTitle.Contains(input.Source));
            expable.AndIF(input.ChannelId>0, a => a.ChannelId == input.ChannelId);

            expable.AndIF(input.Top ==1, a => a.Top == 1);
            expable.AndIF(input.Recommend == 1, a => a.Recommend == 1);
            expable.AndIF(input.Hot == 1, a => a.Hot == 1);
            expable.AndIF(input.Color == 1, a => a.Color == 1);

            expable.AndIF(!string.IsNullOrEmpty(input.GroupName), a => a.GroupNameCollection.Contains(input.GroupName));
            expable.AndIF(!string.IsNullOrEmpty(input.TagName), a => a.Tags.Contains(input.TagName));

            var exp = expable.ToExpression();
           

            Expression<Func<CmsContentEntity, object>> expressionOrder;
            expressionOrder=input.Field switch
            {
                0 => a => a.Hits,
                1=> a => a.Downloads,
                2=> a=> a.Top,
                3=>a => a.Hot,
                4 => a => a.Color,
                5 => a => a.AddTime,
                6 => a => a.Taxis,
                _ =>a => a.Id
            };
            var result = await _contentService.PageDynamicList(exp, (input.Page<0?1: input.Page), (input.Limit>50?20: input.Limit), input.Order==1?true:false, expressionOrder, a => new {
                a.Id,
                a.Title,
                a.SubTitle,
                a.Summary,
                a.Hits,
                a.Tags,
                a.GroupNameCollection,
                a.Top,
                a.Recommend,
                a.Hot,
                a.Color,
                a.ChannelId,
                a.AddTime,
                a.Author,
                a.LinkType,
                a.LinkUrl,
                a.ImageUrlIds
            });
           
            List<ContentPageOutput> list = new List<ContentPageOutput>();
            foreach (var item in result.Item1)
            {
                ContentPageOutput m = new ContentPageOutput();
                var filelist = await _fileService.CustomerFileList(item.ImageUrlIds);
                var urllist = new List<string>();
                foreach (var file in filelist)
                {
                    //urllist.Add(App.HttpContext.Request.Host.ToString()+file["fpath"]);
                    urllist.Add(file["fpath"].ToString());
                    break;
                }
                m.Id = item.Id;
                m.Title = item.Title;
                m.SubTitle = item.SubTitle;
                m.Summary = item.Summary;
                m.Hits = item.Hits;
                m.Top = item.Top;
                m.Recommend = item.Recommend;
                m.Hot = item.Hot;
                m.Color = item.Color;
                m.LinkType = item.LinkType;
                m.LinkUrl = item.LinkUrl;
                m.Tags = item.Tags;
                m.GroupNames = item.GroupNameCollection;
                m.ChannelId = item.ChannelId;
                m.AddTime = item.AddTime;
                m.Author = item.Author;
                m.ImageUrls = urllist.ToArray();
                list.Add(m);
            }

            return new PageResult<ContentPageOutput>(input.Page, input.Limit
              , result.Item3, result.Item2, list);
        }


        /// <summary>
        /// 按条件获取内容List(栏目查询子集,属性(顶,荐,热,醒 并集)图片只返回多张)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("api/content/pageContainsList")]
        public async Task<PageResult<ContentPageOutput>> GetContainsList([FromQuery] ContentInput input)
        {
            var expable = Expressionable.Create<CmsContentEntity>();
            expable.And(a => a.Checked == 3);
            expable.AndIF(!string.IsNullOrEmpty(input.Title), a => a.Title.Contains(input.Title));
            expable.AndIF(!string.IsNullOrEmpty(input.SubTitle), a => a.SubTitle.Contains(input.SubTitle));
            expable.AndIF(!string.IsNullOrEmpty(input.SubTitle), a => a.SubTitle.Contains(input.SubTitle));
            expable.AndIF(!string.IsNullOrEmpty(input.Author), a => a.SubTitle.Contains(input.Author));
            expable.AndIF(!string.IsNullOrEmpty(input.Source), a => a.SubTitle.Contains(input.Source));
            expable.AndIF(input.ChannelId > 0, a => a.ChannelId == input.ChannelId);


            var expableAttr = Expressionable.Create<CmsContentEntity>();
            expableAttr.Or(a => true);
            if (input.Top == 1) //置顶
            {
                expableAttr.Or(a => a.Top == 1);
            }
            if (input.Recommend == 1) //推荐
            {
                expableAttr.Or(a => a.Recommend == 1);
            }
            if (input.Hot == 1) //热点
            {
                expableAttr.Or(a => a.Hot == 1);
            }
            if (input.Color == 1) //醒目
            {
                expableAttr.Or(a => a.Color == 1);
            }
            expable.And(expableAttr.ToExpression());

            if (input.ChannelId>0)
            {
                var channelModel = await _channelService.GetByIdAsync(input.ChannelId);
                string parentpath = string.IsNullOrEmpty(channelModel.ParentsPath) ? channelModel.Id.ToString() : channelModel.ParentsPath + "," + channelModel.Id.ToString();
                expable.And(a => parentpath.GetStringToLongArryNoNull().Contains(a.ChannelId));
            }

            expable.AndIF(!string.IsNullOrEmpty(input.GroupName), a => a.GroupNameCollection.Contains(input.GroupName));
            expable.AndIF(!string.IsNullOrEmpty(input.TagName), a => a.Tags.Contains(input.TagName));

            var exp = expable.ToExpression();

            Expression<Func<CmsContentEntity, object>> expressionOrder;
            expressionOrder = input.Field switch
            {
                0 => a => a.Hits,
                1 => a => a.Downloads,
                2 => a => a.Top,
                3 => a => a.Hot,
                4 => a => a.Color,
                5 => a => a.AddTime,
                6=>  a => a.Taxis,
                _ => a => a.Id
            };
            var result = await _contentService.PageDynamicList(exp, (input.Page < 0 ? 1 : input.Page), (input.Limit > 50 ? 20 : input.Limit), input.Order == 1 ? true : false, expressionOrder, a => new {
                a.Id,
                a.Title,
                a.SubTitle,
                a.Summary,
                a.Hits,
                a.Tags,
                a.GroupNameCollection,
                a.Top,
                a.Recommend,
                a.Hot,
                a.Color,
                a.ChannelId,
                a.AddTime,
                a.Author,
                a.LinkType,
                a.LinkUrl,
                a.ImageUrlIds
            });

            List<ContentPageOutput> list = new List<ContentPageOutput>();
            foreach (var item in result.Item1)
            {
                ContentPageOutput m = new ContentPageOutput();
                var filelist = await _fileService.CustomerFileList(item.ImageUrlIds);
                var urllist = new List<string>();
                foreach (var file in filelist)
                {
                    //urllist.Add(App.HttpContext.Request.Host.ToString()+file["fpath"]);
                    urllist.Add(file["fpath"].ToString());
                }
                m.Id = item.Id;
                m.Title = item.Title;
                m.SubTitle = item.SubTitle;
                m.Summary = item.Summary;
                m.Hits = item.Hits;
                m.Top = item.Top;
                m.Recommend = item.Recommend;
                m.Hot = item.Hot;
                m.Color = item.Color;
                m.LinkType = item.LinkType;
                m.LinkUrl = item.LinkUrl;
                m.Tags = item.Tags;
                m.GroupNames = item.GroupNameCollection;
                m.ChannelId = item.ChannelId;
                m.AddTime = item.AddTime;
                m.Author = item.Author;
                m.ImageUrls = urllist.ToArray();
                list.Add(m);
            }

            return new PageResult<ContentPageOutput>(input.Page, input.Limit
              , result.Item3, result.Item2, list);
        }

        /// <summary>
        /// 获取内容详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("api/content/detail")]
        public async Task<ContentOutput> GetDetail(long id)
        {
            var result= await _contentService.GetByIdAsync(id);
            var data = result.Adapt<ContentOutput>();
            //处理附件
            data.ImageUrls = await GetContentFiles(result.ImageUrlIds);
            data.VideoUrls = await GetContentFiles(result.VideoUrlIds);
            data.FileUrls = await GetContentFiles(result.FileUrlIds);
            return data;
        }

        #region 私有方法
        private async  Task<string[]> GetContentFiles(string ids)
        {
            var filelist = await _fileService.CustomerFileList(ids);
            var urllist = new string[filelist.Count];
            for (int i = 0; i < filelist.Count; i++)
            {
                var file = filelist[i];
                urllist[i] = file["fpath"].ToString();
            }
            return urllist;
        }
        #endregion
    }
}
